#ifndef TABLAAVL_CPP
#define TABLAAVL_CPP

#include "TablaAVL.h"
#include "Cadena.h"
#include "ComparadorTuplaClave.h"

 

 
template <class C, class V>
TablaAVL<C,V>::TablaAVL(const Puntero<Comparador<C>> comparador)//:tabla(new ComparadorTuplaClave<C,V>(comparador))

{ 
	tabla = new AVL<Tupla<C,V>>(new ComparadorTuplaClave<C,V>(comparador));
	 
 
}


//TODO AGREGAR ITERADOR
template <class C, class V>
TablaAVL<C,V>::TablaAVL(Iterador<Tupla<C,V>> iterador, const Puntero<Comparador<C>> comparador)//:tabla(new ComparadorTuplaClave<C,V>(comparador))
{
 	this->tabla= new AVL<Tupla<C,V>>(new ComparadorTuplaClave<C,V>(comparador));
	for (Iterador<T> it =  ObtenerIterador();it.HayElemento() ;it++)
	{
		Agregar(it.ElementoActual());
	}
	
}

template <class C, class V>
bool TablaAVL<C,V>::Agregar(const C& c, const V& v)
{
	
	Tupla<C,V> tupla = Tupla<C,V>(c,v);
	 if(!this->tabla->Existe(tupla.Dato1))
	 {
		 tabla->Insertar(tupla);
		 return true;
	 }
	 else
		 return false;
	 
}

/* retorna true SII encuentra un elemento con la clave a borrar */
template <class C, class V>
bool TablaAVL<C,V>::Borrar(const C& c)
{
 	
	if(tabla->Existe(c))
	{
	 	tabla->Borrar(c);
		return true;
	}
	return false;
	}

template <class C, class V>
void TablaAVL<C,V>::BorrarTodos()
{
	 tabla->BorrarTodo();
}

template <class C, class V>
Puntero<Tabla<C,V>> TablaAVL<C,V>::Clonar() const
{
	Puntero<Comparador<C>> compClave = new ComparadorClave<C>();
	Puntero<TablaAVL<C,V>> clon = new TablaAVL<C,V>(compClave);
	clon->tabla  = this->tabla->Clonar();
	return clon;
}

/* PREDICADOS */
template <class C, class V>
bool TablaAVL<C,V>::EstaVacia() const
{
	 return this->tabla->EsVacio();
}

template <class C, class V>
bool TablaAVL<C,V>::EstaLlena() const
{
	return NULL;
}

template <class C, class V>
bool TablaAVL<C,V>::Pertenece(const C& c) const
{

	return tabla->Existe(c);
   }

/* SELECTORAS */
template <class C, class V>
const V& TablaAVL<C,V>::Obtener(const C& c) const
{
	return tabla->Recuperar(c).Dato2; 
}

template <class C, class V>
bool TablaAVL<C,V>::IntentarObtener(const C& c, V& v) const
{ 

	
	Tupla<C,V> tupla = Tupla<C,V>(c,v);
	if(Pertenece(c))
	{
		v= tabla->Recuperar(tupla).Dato2;
		return true;
	}
	return false;
	}

template <class C, class V>
nat TablaAVL<C,V>::Largo() const
{
	return 0;
}
template <class C, class V>
Iterador<C> TablaAVL<C,V>::Claves() const
{

	return ObtenerIterador().Convert<C, ConversorTuplaDato1<C,V>>();

}

template <class C, class V>
Iterador<V> TablaAVL<C,V>::Valores() const
{
	return ObtenerIterador().Convert<V, ConversorTuplaDato2<C,V>>();
}

template <class C, class V>
Iterador<Tupla<C,V>> TablaAVL<C,V>::ObtenerIterador() const
{
	 return tabla->ObtenerIterador();
}

//template <class C, class V>
//void TablaAvl<c,v>::imprimir(pnodoavl avl ) const
//{
//	if (avl){
//		cout<<"(";
//		imprimir(avl->izq);
//		cout << ")";
//		cout << avl-> dato.Dato1 << "-"<< avl->fb;
//		cout<< " (";
//		imprimir(avl->der);
//		cout<< ")"; 
//	}

#endif